#pragma once

#define ADNCI_MSG_CONNECTED     1
#define ADNCI_MSG_DISCONNECTED  2
#define ADNCI_MSG_UNKNOWN       3

typedef unsigned int mach_error_t;
typedef unsigned int afc_error_t;
typedef unsigned long long afc_file_ref;

struct am_device_notification_callback_info {
    struct am_device *dev;  /* 0    device */ 
    unsigned int msg;       /* 4    one of ADNCI_MSG_* */
};

typedef void(*am_device_notification_callback)(struct
    am_device_notification_callback_info *);

//struct am_device {
//    unsigned char unknown0[16]; /* 0 - zero */
//    unsigned int device_id;     /* 16 */
//    unsigned int product_id;    /* 20 - set to AMD_IPHONE_PRODUCT_ID */
//    char *serial;               /* 24 - set to AMD_IPHONE_SERIAL */
//    unsigned int unknown1;      /* 28 */
//    unsigned char unknown2[4];  /* 32 */
//    unsigned int lockdown_conn; /* 36 */
//    unsigned char unknown3[8];  /* 40 */
//};

struct am_device {
    unsigned char unknown0[0x10]; /* 0 - zero */
    unsigned int device_id;     /* 16 */
    unsigned int product_id;    /* 20 - set to AMD_IPHONE_PRODUCT_ID */
    char *serial;               /* 24 - set to AMD_IPHONE_SERIAL */
    unsigned int unknown1;      /* 28 */
    unsigned char unknown2[0x4];  /* 32 */
    unsigned int lockdown_conn; /* 36 */
    unsigned char unknown3[0x8];  /* 40 */
    unsigned char unknown4[0x61];  /* 40 */
    unsigned char unknown5[0x8];  /* 40 */
};

struct am_device_notification {
    unsigned int unknown0;                      /* 0 */
    unsigned int unknown1;                      /* 4 */
    unsigned int unknown2;                      /* 8 */
    am_device_notification_callback callback;   /* 12 */ 
    unsigned int unknown3;                      /* 16 */
};

struct afc_connection {
	unsigned int handle;
	unsigned int unknown0;
	unsigned char unknown1;
	unsigned char padding[3];
	unsigned int unknown2;
	unsigned int unknown3;
	unsigned int unknown4;
	unsigned int fs_block_size;
	unsigned int sock_block_size;
	unsigned int io_timeout;
	void* afc_lock;
	unsigned int context;
};

struct afc_device_info {
	unsigned char unknown[12];
};

struct afc_directory {
	unsigned char unknown;
};

struct afc_dictionary {
    unsigned char unknown;   /* size unknown */
};

typedef void* (*FunType_CFStringCreateWithCString)(void* allocator, const char* data, unsigned int encoding);

typedef mach_error_t (*FunType_AMDeviceNotificationSubscribe)(am_device_notification_callback
																callback, unsigned int unused0, unsigned int unused1, unsigned int
																dn_unknown3, struct am_device_notification **notification);

typedef mach_error_t (*FunType_AMDeviceNotificationUnsubscribe)(am_device_notification *notification);

typedef mach_error_t (*FunType_AMDeviceConnect)(struct am_device *device);

typedef int (*FunType_AMDeviceIsPaired)(struct am_device *device);

typedef mach_error_t (*FunType_AMDeviceValidatePairing)(struct am_device *device);

typedef mach_error_t (*FunType_AMDeviceStartSession)(struct am_device *device);

typedef mach_error_t (*FunType_AMDeviceStartService)(struct am_device *device, void* 
													service_name, afc_connection **handle, unsigned int *
													unknown);

typedef afc_error_t (*FunType_AFCConnectionOpen)(afc_connection *handle, unsigned int io_timeout,
												struct afc_connection **conn);

typedef mach_error_t (*FunType_AMDeviceStopSession)(struct am_device *device);

typedef afc_error_t (*FunType_AFCConnectionClose)(struct afc_connection *conn);

typedef mach_error_t (*FunType_AMDeviceDisconnect)(struct am_device *device);

typedef afc_error_t (*FunType_AFCDirectoryOpen)(struct afc_connection *conn, char *path, struct
    afc_directory **dir);

typedef afc_error_t (*FunType_AFCDirectoryRead)(struct afc_connection *conn/*unsigned int unused*/, struct afc_directory *dir,
    char **dirent);

typedef afc_error_t (*FunType_AFCDirectoryClose)(afc_connection *conn, struct afc_directory *dir);

typedef afc_error_t (*FunType_AFCDirectoryCreate)(afc_connection *conn, char *dirname);

typedef afc_error_t (*FunType_AFCRemovePath)(afc_connection *conn, char *dirname);

typedef afc_error_t (*FunType_AFCFileRefOpen)(struct afc_connection *conn, char *path, unsigned
    long long int mode, afc_file_ref *ref);

typedef afc_error_t (*FunType_AFCFileRefRead)(struct afc_connection *conn, afc_file_ref ref,
    void *buf, unsigned int *len);

typedef afc_error_t (*FunType_AFCFileRefWrite)(struct afc_connection *conn, afc_file_ref ref,
    void *buf, unsigned int len);

typedef afc_error_t (*FunType_AFCFileRefClose)(struct afc_connection *conn, afc_file_ref ref);

typedef afc_error_t (*FunType_AFCFileRefSeek)(struct afc_connection *conn, afc_file_ref ref, 
	unsigned long long offset1, unsigned long long offset2);

typedef afc_error_t (*FunType_AFCFileInfoOpen)(struct afc_connection *conn, char *path, struct
    afc_dictionary **info);

typedef afc_error_t (*FunType_AFCKeyValueRead)(struct afc_dictionary *dict, char **key, char **
    val);

typedef afc_error_t (*FunType_AFCKeyValueClose)(struct afc_dictionary *dict);


